package com.kye.express.business.waybill.waybill_detail;

import android.content.Context;
import android.text.TextUtils;

import com.baidu.mapapi.model.LatLng;
import com.baidu.trace.LBSTraceClient;
import com.baidu.trace.api.track.HistoryTrackRequest;
import com.baidu.trace.api.track.HistoryTrackResponse;
import com.baidu.trace.api.track.OnTrackListener;
import com.baidu.trace.api.track.TrackPoint;
import com.kye.base.Logger;
import com.kye.base.utils.GsonUtils;
import com.kye.express.business.map.MapUtils;
import com.kye.express.business.waybill.waybill_detail.service.SendArrivedDateService;
import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.ErrorView;
import com.kye.express.contract.base.view.IView;
import com.kye.express.contract.base.view.LoadingView;
import com.kye.express.view.ToastManager;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.UserSession;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.dstance.DstanceBean;
import com.kye.model.bean.logistics.LogisticsDriverInfoBean;
import com.kye.model.bean.logistics.LogisticsUrgeResultBean;
import com.kye.model.bean.logistics.LogisticsWayBillDetailResultBean;
import com.kye.model.bean.logistics.LogisticsWayBillResultDataBean;
import com.kye.model.bean.logistics.LogisticsWayBillRouterDataBean;
import com.kye.model.bean.logistics.RequestLogisticsDriverInfo;
import com.kye.model.bean.logistics.RouterStatusViewType;
import com.kye.model.bean.logistics.request.RequestLogisticsPlanReceiveTime;
import com.kye.model.bean.logistics.request.RequestLogisticsSendDistance;
import com.kye.model.bean.logistics.request.RequestLogisticsUrge;
import com.kye.model.bean.logistics.request.RequestLogisticsWayBillDetail;
import com.kye.model.bean.logistics.request.RequestPostLogisticsUrgeMessage;
import com.kye.model.bean.user.User;
import com.kye.model.datasource.LogisticsDataSource;

import org.reactivestreams.Publisher;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.SingleObserver;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Function4;
import io.reactivex.functions.Predicate;
import io.reactivex.processors.FlowableProcessor;
import io.reactivex.processors.PublishProcessor;
import io.reactivex.schedulers.Schedulers;

public interface WayBillDetailContract {

    interface WayBillDetailView extends IView, LoadingView, ErrorView {

        void onUser(User user);

        void getLogisticsWayBillDetailSuccess(LogisticsWayBillDetailResultBean logisticsWayBillDetailResultBean);

        void getLogisticsWayBillDetailFailed(String msg);

        void getLogisticsWayBillDetailFailed(Throwable e);

        void updateLogisticsRounterStatus(List<RouterStatusTimeLineView.RouterStatusTimeLineModel> routerStatusTimeLineModels, boolean isFinished);

        void postWayBillUrgeSuccess(LogisticsUrgeResultBean logisticsUrgeResultBean);

        void postWayBillUrgeMessageSuccess();

        void getLogisticsSendDistance(DstanceBean dstanceBean, String waybill);

        void onMoveCar(LatLng latLng);

        void disableModifyArriveTimeButton();

        void enableModifyArriveTimeButton();

        void modifyPlanArriveTimeSuccess();

        void modifyPlanArriveTimeFailed(String msg);

        LogisticsWayBillDetailResultBean getLogisticsWayBillDetailResultBean();

        void getDriverInfoSuccess(LogisticsDriverInfoBean logisticsDriverInfoBean);

        void updateWaybillDeliveryDistanceInfo(DstanceBean dstanceBean);
    }

    class WayBillDetailPresenter extends BasePresenter<WayBillDetailView> {

        private static final long TIME_LONG = 300;
        private LogisticsDataSource logisticsDataSource;
        private LBSTraceClient mLBSTraceClient;
        private FlowableProcessor<List<LatLng>> mTrackPointListResult = PublishProcessor.<List<LatLng>>create().toSerialized();

        private OnTrackListener mOnTrackListener = new OnTrackListener() {

            @Override
            public void onHistoryTrackCallback(HistoryTrackResponse historyTrackResponse) {
                super.onHistoryTrackCallback(historyTrackResponse);
                List<TrackPoint> trackPoints = historyTrackResponse.getTrackPoints();
                Logger.d(historyTrackResponse);
                List<LatLng> latLngs = new ArrayList<>();
                if (trackPoints != null && trackPoints.size() > 1) {
                    for (int i = 0; i < trackPoints.size(); i++) {
                        latLngs.add(MapUtils.convertTrace2Map(trackPoints.get(i).getLocation()));
                    }
                    mTrackPointListResult.onNext(latLngs);
                }
            }
        };
        private SendArrivedDateService sendArrivedDateService;
        private SendArrivedTimeModel[] firstDayTimes; // 第一天的时间区间
        private SendArrivedTimeModel[] normalDayTimes; // 中间的时间区间
        private SendArrivedTimeModel[] lastDayTimes; // 最后一天的时间区间
        private SendArrivedDateModel[] days; // 总共可选的天数
        private String[] firstDayTimesShow; // 第一天的时间区间, 用于显示
        private String[] normalDayTimesShow; // 中间的时间区间, 用于显示
        private String[] lastDayTimesShow; // 最后一天的时间区间, 用于显示
        private String[] daysShow; // 总共可选的天数, 用于显示

        public WayBillDetailPresenter() {
            logisticsDataSource = new LogisticsDataSource();
            sendArrivedDateService = new SendArrivedDateService();
        }

        @Override
        public void bind(WayBillDetailView view) {
            super.bind(view);
            UserSession.getInstance()
                    .getUserForRx()
                    .compose(getView().bindToLifecycleDestroy())
                    .subscribe(new Consumer<User>() {
                        @Override
                        public void accept(User user) throws Exception {
                            getView().onUser(user);
                        }
                    });

            mTrackPointListResult.flatMap(new Function<List<LatLng>, Publisher<LatLng>>() {

                @Override
                public Publisher<LatLng> apply(List<LatLng> latLngs) throws Exception {
                    return Flowable.create(new FlowableOnSubscribe<LatLng>() {
                        @Override
                        public void subscribe(FlowableEmitter<LatLng> e) throws Exception {
                            double jianju = TIME_LONG * 1000 / (latLngs.size() - 1);
                            for (int i = 0; i < latLngs.size() - 1; i++) {
                                LatLng startPoint = latLngs.get(i);
                                LatLng endPoint = latLngs.get(i + 1);

                                double slope = MapUtils.getSlope(startPoint, endPoint);
                                //是不是正向的标示（向上设为正向）
                                boolean isReverse = (startPoint.latitude > endPoint.latitude);

                                double intercept = MapUtils.getInterception(slope, startPoint);

                                int v = (int) jianju / 100;
//                                double xMoveDistance = isReverse ? MapUtils.getXMoveDistance(slope)
//                                        : -1 * MapUtils.getXMoveDistance(slope);

                                double xMoveDistance = isReverse ? MapUtils.getXMoveDistance(slope, startPoint, endPoint, v) : -1 * MapUtils.getXMoveDistance(slope, startPoint, endPoint, v);

                                int x = 0;
                                for (double j = startPoint.latitude; x < v; j = j - xMoveDistance, x++) {
//                                for (double j = startPoint.latitude;
//                                     !((j > endPoint.latitude) ^ isReverse);
//                                     j = j - xMoveDistance) {
                                    LatLng latLng;
                                    if (slope != Double.MAX_VALUE) {
                                        latLng = new LatLng(j, (j - intercept) / slope);
                                    } else {
                                        latLng = new LatLng(j, startPoint.longitude);
                                    }

                                    e.onNext(latLng);

                                    try {
                                        Thread.sleep(100);
                                    } catch (Throwable ignored) {}
                                }
                            }
                        }
                    }, BackpressureStrategy.DROP)
                            .subscribeOn(Schedulers.io());
                }
            })
                    .subscribeOn(Schedulers.io())
                    .compose(getView().bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<LatLng>() {
                        @Override
                        public void accept(LatLng latLng) throws Exception {
                            Logger.d(latLng);
                            getView().onMoveCar(latLng);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                        }
                    });
        }

        public Single<OpenApiResult<LogisticsWayBillDetailResultBean>> getLogisticsWayBillDetailSingle(User user, String waybill) {
            return
                    Single.just(new RequestLogisticsWayBillDetail())
                            .subscribeOn(Schedulers.io())
                            .doOnSuccess(new Consumer<RequestLogisticsWayBillDetail>() {
                                @Override
                                public void accept(RequestLogisticsWayBillDetail requestLogisticsWayBillDetail) throws Exception {
                                    requestLogisticsWayBillDetail.setPhone(user.getPhone());
                                    requestLogisticsWayBillDetail.setWaybill(waybill);
                                }
                            })
                            .flatMap(new Function<RequestLogisticsWayBillDetail, SingleSource<OpenApiResult<LogisticsWayBillDetailResultBean>>>() {
                                @Override
                                public SingleSource<OpenApiResult<LogisticsWayBillDetailResultBean>> apply(RequestLogisticsWayBillDetail requestLogisticsWayBillDetail) throws Exception {
                                    return logisticsDataSource.getLogisticsWayBillDetail(requestLogisticsWayBillDetail)
                                            .compose(getView().bindToLifecycleDestroy());
                                }
                            })
                            .doOnSuccess(new Consumer<OpenApiResult<LogisticsWayBillDetailResultBean>>() {
                                @Override
                                public void accept(OpenApiResult<LogisticsWayBillDetailResultBean> logisticsWayBillDetailResultBeanOpenApiResult) throws Exception {
                                    if (logisticsWayBillDetailResultBeanOpenApiResult.getData().getResult() == null ||
                                            logisticsWayBillDetailResultBeanOpenApiResult.getData().getResult().isEmpty() ||
                                            !TextUtils.isEmpty(logisticsWayBillDetailResultBeanOpenApiResult.getData().getResult().get(0).getSigningTime())) {
                                        return;
                                    }

                                    getWaybillDeliveryDistanceInfo(waybill);
                                }
                            })
                            .doOnSuccess(new Consumer<OpenApiResult<LogisticsWayBillDetailResultBean>>() {
                                @Override
                                public void accept(OpenApiResult<LogisticsWayBillDetailResultBean> logisticsWayBillDetailResultBeanOpenApiResult) throws Exception {
                                    if (logisticsWayBillDetailResultBeanOpenApiResult.isSuccess()) {
                                        LogisticsWayBillResultDataBean logisticsWayBillResultDataBean = logisticsWayBillDetailResultBeanOpenApiResult.getData().getResult().get(0);
                                        String signingTime = logisticsWayBillResultDataBean.getSigningTime();
                                        if (TextUtils.isEmpty(signingTime)) {
                                            // 运单未签收获取司机信息
                                            getDriverInfo(user.getPhone(), waybill);
                                        }
                                    }
                                }
                            })
                            .observeOn(AndroidSchedulers.mainThread());
        }

        private void getWaybillDeliveryDistanceInfo(String waybill) {
            logisticsDataSource.getLogisticsSendDistance(new RequestLogisticsSendDistance(waybill))
                    .filter(new Predicate<OpenApiResult<DstanceBean>>() {
                        @Override
                        public boolean test(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData().getDistance() <= 10F;
                        }
                    })
                    .map(new Function<OpenApiResult<DstanceBean>, DstanceBean>() {
                        @Override
                        public DstanceBean apply(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData();
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DstanceBean>() {
                        @Override
                        public void accept(DstanceBean dstanceBean) throws Exception {
                            getView().getLogisticsSendDistance(dstanceBean, waybill);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                        }
                    });
        }

        private void updateWaybillDeliveryDistanceInfo(String waybill) {
            logisticsDataSource.getLogisticsSendDistance(new RequestLogisticsSendDistance(waybill))
                    .filter(new Predicate<OpenApiResult<DstanceBean>>() {
                        @Override
                        public boolean test(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData().getDistance() <= 10F;
                        }
                    })
                    .map(new Function<OpenApiResult<DstanceBean>, DstanceBean>() {
                        @Override
                        public DstanceBean apply(OpenApiResult<DstanceBean> dstanceBeanOpenApiResult) throws Exception {
                            return dstanceBeanOpenApiResult.getData();
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DstanceBean>() {
                        @Override
                        public void accept(DstanceBean dstanceBean) throws Exception {
                            getView().updateWaybillDeliveryDistanceInfo(dstanceBean);
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {

                        }
                    });
        }

        private void getDriverInfo(String phone, String orderCode) {
            Single.just(new RequestLogisticsDriverInfo())
                    .doOnSuccess(new Consumer<RequestLogisticsDriverInfo>() {
                        @Override
                        public void accept(RequestLogisticsDriverInfo requestLogisticsDriverInfo) throws Exception {
                            requestLogisticsDriverInfo.setPhone(phone);
                            requestLogisticsDriverInfo.setWaybill(orderCode);
                            requestLogisticsDriverInfo.setType("1");
                        }
                    })
                    .flatMap(new Function<RequestLogisticsDriverInfo, SingleSource<OpenApiResult<LogisticsDriverInfoBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<LogisticsDriverInfoBean>> apply(RequestLogisticsDriverInfo requestLogisticsDriverInfo) throws Exception {
                            return logisticsDataSource.getLogisticsDriverInfo(requestLogisticsDriverInfo)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<LogisticsDriverInfoBean>() {
                        @Override
                        public void onLoading(Disposable d) {

                        }

                        @Override
                        public void onSuccess(OpenApiResult<LogisticsDriverInfoBean> result, LogisticsDriverInfoBean logisticsDriverInfoBean) {
                            getView().getDriverInfoSuccess(logisticsDriverInfoBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<LogisticsDriverInfoBean> result, int code, String msg) {

                        }

                        @Override
                        public void onOtherError(Throwable e) {

                        }

                        @Override
                        public void onLoaded() {

                        }
                    });
        }

        /**
         * 获取运单详情
         *
         * @param user
         * @param waybill
         */
        public void getLogisticsWayBillDetail(User user, String waybill) {
            getLogisticsWayBillDetailSingle(user, waybill)
                    .subscribe(new OpenApiResultObserver<LogisticsWayBillDetailResultBean>() {
                        @Override
                        public void onLoading(Disposable d) {

                        }

                        @Override
                        public void onSuccess(OpenApiResult<LogisticsWayBillDetailResultBean> result, LogisticsWayBillDetailResultBean logisticsWayBillDetailResultBean) {
                            getView().getLogisticsWayBillDetailSuccess(logisticsWayBillDetailResultBean);
                            // 解析定时派送选择数据
                            getPlanArriveTimeSelectedData(logisticsWayBillDetailResultBean.getResult().get(0).getPlanArriveTime());
                        }

                        @Override
                        public void onApiError(OpenApiResult<LogisticsWayBillDetailResultBean> result, int code, String msg) {
                            getView().getLogisticsWayBillDetailFailed(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().getLogisticsWayBillDetailFailed(e);
                        }

                        @Override
                        public void onLoaded() {

                        }
                    });
        }

        /**
         * 操作后刷新界面
         *
         * @param user
         * @param waybill
         */
        public void refreshLogisticsWayBillDetail(User user, String waybill) {
            getLogisticsWayBillDetailSingle(user, waybill)
                    .subscribe(new OpenApiResultObserver<LogisticsWayBillDetailResultBean>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<LogisticsWayBillDetailResultBean> result, LogisticsWayBillDetailResultBean logisticsWayBillDetailResultBean) {
                            getView().getLogisticsWayBillDetailSuccess(logisticsWayBillDetailResultBean);
                            // 解析定时派送选择数据
                            getPlanArriveTimeSelectedData(logisticsWayBillDetailResultBean.getResult().get(0).getPlanArriveTime());
                        }

                        @Override
                        public void onApiError(OpenApiResult<LogisticsWayBillDetailResultBean> result, int code, String msg) {
                            ToastManager.showCenterForShort(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            ToastManager.showCenterForShort(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        /**
         * 更新运单路由状态
         *
         * @param logisticsWayBillResultDataBean
         */
        public void updateLogisticsRounterStatus(LogisticsWayBillResultDataBean logisticsWayBillResultDataBean) {
            List<LogisticsWayBillRouterDataBean> routerDatas = logisticsWayBillResultDataBean.getData();
            if (routerDatas.size() <= 0) {
                return;
            }
            String signingTime = logisticsWayBillResultDataBean.getSigningTime();
            /**
             * 未签收不显示finished logo
             */
            boolean isFinished = !TextUtils.isEmpty(signingTime);
            Observable.fromIterable(logisticsWayBillResultDataBean.getData())
                    .doOnNext(new Consumer<LogisticsWayBillRouterDataBean>() {
                        @Override
                        public void accept(LogisticsWayBillRouterDataBean logisticsWayBillRouterDataBean) throws Exception {
                            logisticsWayBillRouterDataBean.setFinished(isFinished);
                        }
                    })
                    .toList()
                    .doOnSuccess(new Consumer<List<LogisticsWayBillRouterDataBean>>() {
                        @Override
                        public void accept(List<LogisticsWayBillRouterDataBean> logisticsWayBillRouterDataBeans) throws Exception {
                            Collections.sort(logisticsWayBillRouterDataBeans, new Comparator<LogisticsWayBillRouterDataBean>() {
                                @Override
                                public int compare(LogisticsWayBillRouterDataBean o1, LogisticsWayBillRouterDataBean o2) {
                                    return o2.getUniqId() - o1.getUniqId();
                                }
                            });
                        }
                    })
                    .map(new Function<List<LogisticsWayBillRouterDataBean>, List<RouterStatusTimeLineView.RouterStatusTimeLineModel>>() {
                        @Override
                        public List<RouterStatusTimeLineView.RouterStatusTimeLineModel> apply(List<LogisticsWayBillRouterDataBean> logisticsWayBillRouterDataBeans) throws Exception {
                            List<RouterStatusTimeLineView.RouterStatusTimeLineModel> routerStatusTimeLineModels = new ArrayList<>();
                            /**
                             * 过滤uniqId: 0的无效数据
                             */
                            if (logisticsWayBillRouterDataBeans.size() == 1 && logisticsWayBillRouterDataBeans.get(0).getUniqId() == 0) {
                                // do nothing
                            } else {
                                for (LogisticsWayBillRouterDataBean routerDataBean :
                                        logisticsWayBillRouterDataBeans) {
                                    RouterStatusTimeLineView.RouterStatusTimeLineModel model = new RouterStatusTimeLineView.RouterStatusTimeLineModel();
                                    // 过滤uniqId: 0的无效数据
                                    if (routerDataBean.getUniqId() == 0) {
                                        continue;
                                    }
                                    model.setMessage(routerDataBean.getSendTime());
                                    model.setFinished(routerDataBean.isFinished());
                                    model.setTime(routerDataBean.getUpdateTime());
                                    routerStatusTimeLineModels.add(model);
                                }
                            }
                            return routerStatusTimeLineModels;
                        }
                    })
                    .doOnSuccess(new Consumer<List<RouterStatusTimeLineView.RouterStatusTimeLineModel>>() {
                        @Override
                        public void accept(List<RouterStatusTimeLineView.RouterStatusTimeLineModel> routerStatusTimeLineModels) throws Exception {
                            // 没有路由信息
                            if (routerStatusTimeLineModels.size() <= 0) {
                                return;
                            }
                            // 0 : 完成节点
                            // size - 1 : 开始节点
                            int size = routerStatusTimeLineModels.size();
                            if (size == 1) {
                                /**
                                 * 只有一个数据
                                 */
                                routerStatusTimeLineModels.get(0).setType(RouterStatusViewType.TYPE_ONLY_ONE);
                            } else {
                                /**
                                 * 多个数据
                                 */
                                for (int i = 0; i < size; i++) {
                                    if (i == 0) {
                                        // 路由的最后状态
                                        routerStatusTimeLineModels.get(i).setType(RouterStatusViewType.TYPE_END);
                                    } else if (i == size - 1) {
                                        // 路由的开始状态
                                        routerStatusTimeLineModels.get(i).setType(RouterStatusViewType.TYPE_BEGIN);
                                    } else {
                                        routerStatusTimeLineModels.get(i).setType(RouterStatusViewType.TYPE_NORMAL);
                                    }
                                }
                            }
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<List<RouterStatusTimeLineView.RouterStatusTimeLineModel>>() {
                        @Override
                        public void accept(List<RouterStatusTimeLineView.RouterStatusTimeLineModel> logisticsWayBillRouterDataBeans) throws Exception {
                            Logger.d("update router datas : \n" + GsonUtils.toJsonString(logisticsWayBillRouterDataBeans, true));
                            getView().updateLogisticsRounterStatus(logisticsWayBillRouterDataBeans, isFinished);
                        }
                    });
        }

        /**
         * 崔健
         *
         * @param waybill
         * @param userInfo
         */
        public void postWaybillUrge(String waybill, User userInfo) {
            Single.just(new RequestLogisticsUrge())
                    .doOnSuccess(new Consumer<RequestLogisticsUrge>() {
                        @Override
                        public void accept(RequestLogisticsUrge requestLogisticsUrge) throws Exception {
                            requestLogisticsUrge.setPhone(userInfo.getPhone());
                            requestLogisticsUrge.setSource("APP");
                            requestLogisticsUrge.setType("1"); // 类型（0 取 1派）
                            requestLogisticsUrge.setWaybill(waybill);
                        }
                    })
                    .flatMap(new Function<RequestLogisticsUrge, SingleSource<OpenApiResult<LogisticsUrgeResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<LogisticsUrgeResultBean>> apply(RequestLogisticsUrge requestLogisticsUrge) throws Exception {
                            return logisticsDataSource
                                    .postLogisticsUrge(requestLogisticsUrge)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<LogisticsUrgeResultBean>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<LogisticsUrgeResultBean> result, LogisticsUrgeResultBean logisticsUrgeResultBean) {
                            getView().postWayBillUrgeSuccess(logisticsUrgeResultBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<LogisticsUrgeResultBean> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        /**
         * 发送留言
         *
         * @param urgeMessage
         */
        public void postWaybillUrgeMessage(String urgeMessage, User userInfo, String waybill) {
            Single.just(new RequestPostLogisticsUrgeMessage())
                    .doOnSuccess(new Consumer<RequestPostLogisticsUrgeMessage>() {
                        @Override
                        public void accept(RequestPostLogisticsUrgeMessage requestPostLogisticsUrgeMessage) throws Exception {
                            requestPostLogisticsUrgeMessage.setPhone(userInfo.getPhone());
                            requestPostLogisticsUrgeMessage.setRemark(urgeMessage);
                            requestPostLogisticsUrgeMessage.setWaybill(waybill);
                        }
                    })
                    .flatMap(new Function<RequestPostLogisticsUrgeMessage, SingleSource<OpenApiResult<Object>>>() {
                        @Override
                        public SingleSource<OpenApiResult<Object>> apply(RequestPostLogisticsUrgeMessage requestPostLogisticsUrgeMessage) throws Exception {
                            return logisticsDataSource
                                    .postLogisticsUrgeMessage(requestPostLogisticsUrgeMessage)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().onLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object o) {
                            getView().postWayBillUrgeMessageSuccess();
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
                            getView().onError(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().onError(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().onLoaded();
                        }
                    });
        }

        public void getHistoryTrack(String terminalID, String waybill) {
            Observable.interval(0, TIME_LONG, TimeUnit.SECONDS)
                    .compose(getView().bindToLifecycleDestroy())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            Logger.d("开始请求鹰眼");

                            int tag = 1;
                            long serviceId = 126686;
                            String entityName = terminalID;
                            HistoryTrackRequest historyTrackRequest = new HistoryTrackRequest(tag, serviceId, entityName);
                            long startTime = (System.currentTimeMillis() / 1000) - TIME_LONG;
                            long endTime = System.currentTimeMillis() / 1000;
                            historyTrackRequest.setStartTime(startTime);
                            historyTrackRequest.setEndTime(endTime);

                            mLBSTraceClient.queryHistoryTrack(historyTrackRequest, mOnTrackListener);

                            updateWaybillDeliveryDistanceInfo(waybill);
                        }
                    });
        }



        public void initLBSTraceClient(Context context) {
            if (mLBSTraceClient == null) mLBSTraceClient = new LBSTraceClient(context);
        }

        /**
         * 解析修改派送时间的数据
         * @param planArriveTime
         */
        private void getPlanArriveTimeSelectedData(String planArriveTime) {
            if (TextUtils.isEmpty(planArriveTime)) {
                return;
            }
            /**
             * 是否可以修改定时派送时间
             * 指定派送标识(1 有 0  无 2 已经修改过)
             */
            int sendMark = getView().getLogisticsWayBillDetailResultBean().getResult().get(0).getSendMark();
            if (sendMark == 0 || sendMark == 2) {
                return;
            }
            getAllSendArrivedDate(planArriveTime);
        }

        public void getAllSendArrivedDate(String planArriveTime) {
            Single.zip(
                    sendArrivedDateService.getSendArrivedDateObservable(planArriveTime),
                    sendArrivedDateService.getSendArrivedTimeNormalObservable2(),
                    sendArrivedDateService.getSendArrivedTimeFirstObservable(planArriveTime),
                    sendArrivedDateService.getSendArrivedTimeLastObservable(planArriveTime),
                    new Function4<SendArrivedDateModel[], SendArrivedTimeModel[], SendArrivedTimeModel[], SendArrivedTimeModel[], Boolean>() {
                        @Override
                        public Boolean apply(SendArrivedDateModel[] _days, SendArrivedTimeModel[] _normals, SendArrivedTimeModel[] _firsts, SendArrivedTimeModel[] _lasts) throws Exception {
                            Logger.d("days : \n" + GsonUtils.toJsonString(_days, true));
                            Logger.d("normals : \n" + GsonUtils.toJsonString(_normals, true));
                            Logger.d("firsts : \n" + GsonUtils.toJsonString(_firsts, true));
                            Logger.d("lasts : \n" + GsonUtils.toJsonString(_lasts, true));
                            days = _days;
                            normalDayTimes = _normals;
                            firstDayTimes = _firsts;
                            lastDayTimes = _lasts;
                            return true;
                        }
                    }
            )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<Boolean>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            getView().disableModifyArriveTimeButton();
                        }

                        @Override
                        public void onSuccess(Boolean aBoolean) {
                            tranformPlanArriveSelectedData();
                            getView().enableModifyArriveTimeButton();
                        }

                        @Override
                        public void onError(Throwable e) {
                            getView().enableModifyArriveTimeButton();
                        }
                    });
        }

        /**
         * 转成用于显示的数据
         */
        private void tranformPlanArriveSelectedData() {
            Single.create(new SingleOnSubscribe<Boolean>() {
                @Override
                public void subscribe(SingleEmitter<Boolean> e) throws Exception {
                    daysShow = new String[days.length];
                    for (int i = 0; i < days.length; i++) {
                        daysShow[i] = days[i].getMessageShow();
                    }
                    normalDayTimesShow = new String[normalDayTimes.length];
                    for (int i = 0; i < normalDayTimes.length; i++) {
                        normalDayTimesShow[i] = normalDayTimes[i].getMessageShow();
                    }
                    firstDayTimesShow = new String[firstDayTimes.length];
                    for (int i = 0; i < firstDayTimes.length; i++) {
                        firstDayTimesShow[i] = firstDayTimes[i].getMessageShow();
                    }
                    lastDayTimesShow = new String[lastDayTimes.length];
                    for (int i = 0; i < lastDayTimes.length; i++) {
                        lastDayTimesShow[i] = lastDayTimes[i].getMessageShow();
                    }
                }
            })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept(Boolean aBoolean) throws Exception {

                        }
                    });
        }

        /**
         * 修改定时派送
         */
        public void modifyPlanReceivedDate(String phone, String waybill, String startTime, String endTime) {
            Single.just(new RequestLogisticsPlanReceiveTime())
                    .doOnSuccess(new Consumer<RequestLogisticsPlanReceiveTime>() {
                        @Override
                        public void accept(RequestLogisticsPlanReceiveTime requestLogisticsPlanReceiveTime) throws Exception {
                            requestLogisticsPlanReceiveTime.setStartTime(startTime);
                            requestLogisticsPlanReceiveTime.setEndTime(endTime);
                            requestLogisticsPlanReceiveTime.setPhone(phone);
                            requestLogisticsPlanReceiveTime.setWaybill(waybill);
                            requestLogisticsPlanReceiveTime.setSource("APP");
                        }
                    })
                    .flatMap(new Function<RequestLogisticsPlanReceiveTime, SingleSource<OpenApiResult<Object>>>() {
                        @Override
                        public SingleSource<OpenApiResult<Object>> apply(RequestLogisticsPlanReceiveTime requestLogisticsPlanReceiveTime) throws Exception {
                            return logisticsDataSource.modifySpecifiedTime(requestLogisticsPlanReceiveTime)
                                    .compose(getView().bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<Object>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().disableModifyArriveTimeButton();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<Object> result, Object o) {
                            getView().modifyPlanArriveTimeSuccess();
                        }

                        @Override
                        public void onApiError(OpenApiResult<Object> result, int code, String msg) {
                            getView().modifyPlanArriveTimeFailed(msg);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            getView().modifyPlanArriveTimeFailed(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().enableModifyArriveTimeButton();
                        }
                    });
        }

        public SendArrivedTimeModel[] getFirstDayTimes() {
            return firstDayTimes;
        }

        public SendArrivedTimeModel[] getNormalDayTimes() {
            return normalDayTimes;
        }

        public SendArrivedTimeModel[] getLastDayTimes() {
            return lastDayTimes;
        }

        public SendArrivedDateModel[] getDays() {
            return days;
        }

        public String[] getFirstDayTimesShow() {
            return firstDayTimesShow;
        }

        public String[] getNormalDayTimesShow() {
            return normalDayTimesShow;
        }

        public String[] getLastDayTimesShow() {
            return lastDayTimesShow;
        }

        public String[] getDaysShow() {
            return daysShow;
        }


    }
}
